package org.study.es.api.high;

import org.elasticsearch.action.DocWriteResponse;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.get.GetResult;
import org.elasticsearch.xcontent.XContentType;
import org.study.es.api.model.User;

import java.io.IOException;
import java.util.*;

/**
 * 参考 https://blog.csdn.net/guanshengg/article/details/126315549
 *
 * @author doveylovey
 * @version v1.0.0
 * @email 1135782208@qq.com
 * @date 2023年06月03日
 */
public class RestHighLevelClient4User {
    /**
     * 添加文档：index()中的参数为文档所属的索引名，id()的中参数为文档的id，document()的参数为文档数据，新版本支持直接传入对象
     */
    public static DocWriteResponse.Result addUser(String indexName, User user) throws IOException {
        try (RestHighLevelClient client = RestHighLevelClientUtils.getRestHighLevelClient()) {
            // 创建IndexRequest请求，设置索引名
            IndexRequest indexRequest = new IndexRequest(indexName);
            // 设置文档id
            indexRequest.id(user.getUserId() + "");
            // 以json字符串的形式设置文档内容，也就是准备插入到ES中的数据
            String jsonString = "{" +
                    "\"user\":\"kimchy\"," +
                    "\"postDate\":\"2013-01-30\"," +
                    "\"message\":\"trying out Elasticsearch\"" +
                    "}";
            indexRequest.source(jsonString, XContentType.JSON);
            // 执行请求
            IndexResponse indexResponse = client.index(indexRequest, RequestOptions.DEFAULT);
            DocWriteResponse.Result result = indexResponse.getResult();
            return result;
        }
    }

    /**
     * 查询文档
     */
    public static String getUser(String indexName, String userId) throws IOException {
        try (RestHighLevelClient client = RestHighLevelClientUtils.getRestHighLevelClient()) {
            // 创建GetRequest对象，设置索引名、要查询的文档id
            GetRequest getRequest = new GetRequest(indexName, userId);
            // 执行请求
            GetResponse getResponse = client.get(getRequest, RequestOptions.DEFAULT);
            // 处理查询结果
            String index = getResponse.getIndex();
            long version = getResponse.getVersion();
            String id = getResponse.getId();
            // 检查文档是否存在
            if (getResponse.isExists()) {
                // 获取文档数据的json字符串形式，可以使用json库转换成Java对象
                String sourceAsString = getResponse.getSourceAsString();
                // 获取文档数据的Map形式
                Map<String, Object> sourceAsMap = getResponse.getSourceAsMap();
                // 获取文档数据的字节数组形式
                byte[] sourceAsBytes = getResponse.getSourceAsBytes();
                return sourceAsString;
            }
            return null;
        }
    }

    /**
     * 修改文档
     */
    public static GetResult updateUser(String indexName, User user) throws IOException {
        try (RestHighLevelClient client = RestHighLevelClientUtils.getRestHighLevelClient()) {
            // 创建UpdateRequest对象，设置索引名、要更新的文档id
            UpdateRequest updateRequest = new UpdateRequest(indexName, user.getUserId() + "");
            // 以map形式，设置需要更新的文档字段
            Map<String, Object> jsonMap = new HashMap<>();
            jsonMap.put("updated", new Date());
            jsonMap.put("reason", "daily update");
            updateRequest.doc(jsonMap);
            // 执行请求
            UpdateResponse updateResponse = client.update(updateRequest, RequestOptions.DEFAULT);
            GetResult getResult = updateResponse.getGetResult();
            return getResult;
        }
    }

    /**
     * 删除文档
     */
    public static DocWriteResponse.Result deleteUser(String indexName, String userId) throws IOException {
        try (RestHighLevelClient client = RestHighLevelClientUtils.getRestHighLevelClient()) {
            // 创建DeleteRequest对象，设置索引名、要删除的文档id
            DeleteRequest deleteRequest = new DeleteRequest(indexName, userId);
            // 执行请求
            DeleteResponse deleteResponse = client.delete(deleteRequest, RequestOptions.DEFAULT);
            DocWriteResponse.Result result = deleteResponse.getResult();
            return result;
        }
    }

    /**
     * 批量添加文档：核心是构建一个泛型为 BulkOperation 的 ArrayList 集合，实质上是将多个请求包装到一个集合中，进行统一请求，进行构建请求时调用 bulk() 方法，实现批量添加效果
     */
    public static void addUserBatch(String indexName, List<User> userList) throws IOException {
        try (RestHighLevelClient client = RestHighLevelClientUtils.getRestHighLevelClient()) {

        }
    }

    /**
     * 批量删除文档
     */
    public static void deleteUserBatch(String indexName, List<Long> userIdList) throws IOException {
        try (RestHighLevelClient client = RestHighLevelClientUtils.getRestHighLevelClient()) {

        }
    }

    /**
     * 全量查询
     */
    public static void searchAll(String indexName) throws IOException {
        try (RestHighLevelClient client = RestHighLevelClientUtils.getRestHighLevelClient()) {

        }
    }

    /**
     * 分页查询：在全量查询的基础上增加了从第几条开始，查询几条
     */
    public static void searchPage(String indexName, Integer pageNum, Integer pageSize) throws IOException {
        try (RestHighLevelClient client = RestHighLevelClientUtils.getRestHighLevelClient()) {

        }
    }

    /**
     * 排序查询
     */
    public static void searchSort(String indexName) throws IOException {
        try (RestHighLevelClient client = RestHighLevelClientUtils.getRestHighLevelClient()) {

        }
    }

    /**
     * 条件查询：includes() 是显示的字段，excludes() 是排除的字段
     */
    public static void searchCondition(String indexName) throws IOException {
        try (RestHighLevelClient client = RestHighLevelClientUtils.getRestHighLevelClient()) {

        }
    }

    /**
     * 组合查询：must 是必须满足所有条件，should 只要满足一个就行
     */
    public static void searchComposite4Must(String indexName) throws IOException {
        try (RestHighLevelClient client = RestHighLevelClientUtils.getRestHighLevelClient()) {

        }
    }

    /**
     * 组合查询：must 是必须满足所有条件，should 只要满足一个就行
     */
    public static void searchComposite4Should(String indexName) throws IOException {
        try (RestHighLevelClient client = RestHighLevelClientUtils.getRestHighLevelClient()) {

        }
    }

    /**
     * 范围查询：gte()表示取大于等于，gt()表示大于，lte()表示小于等于
     */
    public static void searchRange(String indexName) throws IOException {
        try (RestHighLevelClient client = RestHighLevelClientUtils.getRestHighLevelClient()) {

        }
    }

    /**
     * 模糊查询：fuzziness 表示差几个可以查询出来
     */
    public static void searchFuzzy(String indexName) throws IOException {
        try (RestHighLevelClient client = RestHighLevelClientUtils.getRestHighLevelClient()) {

        }
    }

    /**
     * 高亮查询
     */
    public static void searchHighlight(String indexName) throws IOException {
        try (RestHighLevelClient client = RestHighLevelClientUtils.getRestHighLevelClient()) {

        }
    }

    /**
     * 聚合查询：取最大年龄
     */
    public static void searchAggregations(String indexName) throws IOException {
        try (RestHighLevelClient client = RestHighLevelClientUtils.getRestHighLevelClient()) {

        }
    }

    /**
     * 分组查询：实质上是聚合查询的一种
     */
    public static void searchGroup(String indexName) throws IOException {
        try (RestHighLevelClient client = RestHighLevelClientUtils.getRestHighLevelClient()) {

        }
    }
}
